package com.yugu.park.business.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.yugu.park.business.entity.CardInfo;
import com.yugu.park.business.entity.MemberInfo;
import com.yugu.park.business.mapper.CardInfoMapper;
import com.yugu.park.business.service.MemberInfoService;
import com.yugu.park.business.mapper.MemberInfoMapper;
import com.yugu.park.dto.CardDto;
import com.yugu.park.dto.MemberInfoDto;
import com.yugu.park.enums.SequenceTypeEnum;
import com.yugu.park.exception.BusinessException;
import com.yugu.park.system.service.TSysSequenceService;
import com.yugu.util.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Date;
import java.util.List;

/**
* @author Noble-Six
* @description 针对表【t_member_info(会员信息表)】的数据库操作Service实现
* @createDate 2024-04-25 11:02:27
*/
@Service
public class MemberInfoServiceImpl extends ServiceImpl<MemberInfoMapper, MemberInfo>
    implements MemberInfoService{

    @Resource
    private MemberInfoMapper memberInfoMapper;
    @Resource
    private TSysSequenceService tSysSequenceService;
    @Resource
    private CardInfoMapper cardInfoMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addOrUpdate(MemberInfoDto infoDto) {
        MemberInfo old = memberInfoMapper.selectById(infoDto.getId());
        if (old != null) {
            BeanCopyUtil.copyProperties(infoDto,old);
            LambdaQueryWrapper<MemberInfo> memberWrapper = new LambdaQueryWrapper<>();
            memberWrapper.eq(MemberInfo::getMobile,infoDto.getMobile());
            List<MemberInfo> memberInfos = memberInfoMapper.selectList(memberWrapper);
            if (memberInfos.size() > 1){
                throw new BusinessException("手机号重复");
            }
            memberInfoMapper.updateById(old);
            if (CollectionUtil.isNotEmpty(infoDto.getCards())){
                List<CardInfo> cards = infoDto.getCards();
                for (CardInfo card : cards) {
                    if (StringUtils.isNotBlank(card.getId()) && cardInfoMapper.selectById(card.getId())!= null){
                        cardInfoMapper.updateById(card);
                    }else if(StringUtils.isBlank(card.getId())){
                        String memberNum = memberInfoMapper.selectById(infoDto.getId()).getNum();
                        LambdaQueryWrapper<CardInfo> cardWrapper = new LambdaQueryWrapper<>();
                        cardWrapper.eq(CardInfo::getMemberId,infoDto.getId());
                        cardWrapper.orderByDesc(CardInfo::getNum);
                        List<CardInfo> cardInfos = cardInfoMapper.selectList(cardWrapper);
                        setCardNum(card, memberNum, cardInfos);
                        setCardBaseInfo(infoDto, card);
                        cardInfoMapper.insert(card);
                    }
                }
            }
        }else {
            infoDto.setId(IdUtil.simpleUUID());
            LambdaQueryWrapper<MemberInfo> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(MemberInfo::getMobile,infoDto.getMobile());
            MemberInfo memberInfo = memberInfoMapper.selectOne(wrapper);
            if (memberInfo != null) {
                throw new BusinessException("手机号已经使用");
            }
            long next = tSysSequenceService.getNext(SequenceTypeEnum.VIP_NO);
            String no = DataUtils.getNOYear("VIP", next);
            infoDto.setNum(no);
            MemberInfo newMember = new MemberInfo();
            BeanCopyUtil.copyProperties(infoDto,newMember);
            memberInfoMapper.insert(newMember);
            if (CollectionUtil.isNotEmpty(infoDto.getCards())){
                List<CardInfo> cards = infoDto.getCards();
                for (CardInfo card : cards) {
                    setCardBaseInfo(infoDto, card);
                    LambdaQueryWrapper<CardInfo> CardWrapper = new LambdaQueryWrapper<>();
                    CardWrapper.eq(CardInfo::getMemberId,infoDto.getId());
                    CardWrapper.orderByDesc(CardInfo::getNum);
                    List<CardInfo> cardInfos = cardInfoMapper.selectList(CardWrapper);
                    String memberNum = memberInfoMapper.selectById(infoDto.getId()).getNum();
                    setCardNum(card, memberNum, cardInfos);
                    cardInfoMapper.insert(card);
                }
            }
        }

    }

    private void setCardBaseInfo(MemberInfoDto infoDto, CardInfo card) {
        card.setId(IdUtil.simpleUUID());
        card.setBeginDate(new Date());
        card.setMemberId(infoDto.getId());
        Instant instant = card.getBeginDate().toInstant();
        ZonedDateTime zonedDateTime = instant.atZone(ZoneId.systemDefault());
        LocalDate localDate = zonedDateTime.toLocalDate();
        LocalDate localDatePlus = localDate.plusYears(1);
        ZonedDateTime startOfDay = localDatePlus.atStartOfDay(ZoneId.systemDefault());
        Date end = Date.from(startOfDay.toInstant());
        card.setEndDate(end);
    }

    private void setCardNum(CardInfo card, String memberNum, List<CardInfo> cardInfos) {
        if (CollectionUtil.isEmpty(cardInfos)){
            String no1 = memberNum+"01";
            card.setNum(no1);
        }else {
            CardInfo cardInfo = cardInfos.get(0);
            String substring = cardInfo.getNum().substring(12);
            int i = Integer.parseInt(substring);
            i++;
            if (i > 99) {
                throw new IllegalStateException("编号过长");
            }
            String no1 = cardInfo.getNum().substring(0, cardInfo.getNum().length() - 2) + String.format("%02d", i);
            card.setNum(no1);
        }
    }

    @Override
    public PageInfo<MemberInfoDto> page(SearchPage<SysQueryParam> search) {
        PageHelper.startPage(search.getPageNum(),search.getPageSize());
        List<MemberInfoDto> list = memberInfoMapper.page(search.getSearch());
        return PageInfo.of(list);
    }

    @Override
    public List<CardDto> indexGetMemberInfo(SearchPage<SysQueryParam> search) {
        List<CardDto> list = memberInfoMapper.indexPage(search.getSearch());
        return list;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void removeIds(List<String> asList) {
        for (String s : asList) {
            memberInfoMapper.deleteById(s);
            UpdateWrapper<CardInfo> updateWrapper = new UpdateWrapper<>();
            updateWrapper.eq("MEMBER_ID", s);
            updateWrapper.set("DEL_FLAG", 1);
            cardInfoMapper.delete(updateWrapper);
        }


    }

    @Override
    public MemberInfoDto getByMobile(String mobile) {
        LambdaQueryWrapper<MemberInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(MemberInfo::getMobile, mobile);
        MemberInfo one = memberInfoMapper.selectOne(wrapper);
        MemberInfoDto memberInfoDto = new MemberInfoDto();
        BeanCopyUtil.copyProperties(one,memberInfoDto);
        LambdaQueryWrapper<CardInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CardInfo::getMemberId,one.getId());
        queryWrapper.eq(CardInfo::getDelFlag,0);
        List<CardInfo> cardInfos = cardInfoMapper.selectList(queryWrapper);
        memberInfoDto.setCards(cardInfos);
        return memberInfoDto;
    }
}




